<template>
  <div class="container">
    <h1>记账本演示</h1>
    <form @submit.prevent="onSubmit" class="bill-form">
      <div class="form-fields">
        <input v-model="form.description" placeholder="描述" required />
        <input v-model.number="form.amount" type="number" step="0.01" placeholder="金额" required />
        <input v-model="form.category" placeholder="分类" required />
        <select v-model="form.type" required>
          <option value="支出">支出</option>
          <option value="收入">收入</option>
        </select>
        <div class="date-input-wrapper">
          <input v-model="form.date" type="date" required />
          <!-- <span class="date-icon"></span> -->
        </div>
      </div>
      <div class="form-actions">
        <button type="submit" class="main-btn">{{ form.id ? '更新' : '添加' }}</button>
        <button v-if="form.id" type="button" @click="resetForm" class="main-btn cancel-btn">取消</button>
        <button type="button" @click="exportBillsToCSV" class="main-btn export-btn">导出账单</button>
      </div>
    </form>
    <table class="bill-table">
      <thead>
        <tr>
          <th>描述</th>
          <th>金额</th>
          <th>分类</th>
          <th>类型</th>
          <th>日期</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="bill in sortedBills" :key="bill.id">
          <td>{{ bill.description }}</td>
          <td>{{ bill.amount }}</td>
          <td>{{ bill.category }}</td>
          <td>{{ bill.type }}</td>
          <td>{{ bill.date.split('T')[0] }}</td>
          <td>
            <button @click="editBill(bill)">编辑</button>
            <button @click="deleteBillById(bill.id)">删除</button>
          </td>
        </tr>
      </tbody>
    </table>
    <div class="analysis-area">
      <h2>收支分析</h2>
      <div id="pie-chart" style="width:100%;height:400px;"></div>
    </div>
    <div class="analysis-area">
      <h2>分类分析</h2>
      <div id="category-line-chart" style="width:100%;height:400px;"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch, nextTick, computed } from 'vue';
import { getBills, createBill, updateBill, deleteBill, exportBills } from './api';
import * as echarts from 'echarts';

const bills = ref([]);
const form = ref({ description: '', amount: '', category: '', date: '', type: '支出' });
let pieChartInstance = null;
let categoryLineChartInstance = null;

const fetchBills = async () => {
  bills.value = await getBills();
  await nextTick();
  renderPieChart();
  renderCategoryLineChart();
};

onMounted(() => {
  fetchBills();
  nextTick(() => {
    renderPieChart();
    renderCategoryLineChart();
  });
});

watch(bills, () => {
  nextTick(() => {
    renderPieChart();
    renderCategoryLineChart();
  });
});

const resetForm = () => {
  form.value = { description: '', amount: '', category: '', date: '', type: '支出' };
};

const onSubmit = async () => {
  if (form.value.id) {
    await updateBill(form.value.id, form.value);
  } else {
    await createBill(form.value);
  }
  resetForm();
  fetchBills();
};

const editBill = (bill) => {
  form.value = { ...bill, date: bill.date.split('T')[0] };
};

const deleteBillById = async (id) => {
  await deleteBill(id);
  fetchBills();
  await nextTick();
  renderPieChart();
  renderCategoryLineChart();
};

const exportBillsToCSV = async () => {
  const res = await exportBills();
  const url = window.URL.createObjectURL(new Blob([res.data]));
  const link = document.createElement('a');
  link.href = url;
  link.setAttribute('download', 'bills.csv');
  document.body.appendChild(link);
  link.click();
  link.remove();
};

function renderPieChart() {
  if (!document.getElementById('pie-chart')) return;
  if (!pieChartInstance) {
    pieChartInstance = echarts.init(document.getElementById('pie-chart'));
  }
  const income = bills.value.filter(b => b.type === '收入').reduce((sum, b) => sum + Number(b.amount), 0);
  const expense = bills.value.filter(b => b.type === '支出').reduce((sum, b) => sum + Number(b.amount), 0);
  pieChartInstance.setOption({
    title: { text: '收支占比', left: 'center' },
    tooltip: { trigger: 'item' },
    legend: { orient: 'vertical', left: 'left' },
    series: [
      {
        name: '收支',
        type: 'pie',
        radius: '60%',
        data: [
          { value: income, name: '收入' },
          { value: expense, name: '支出' }
        ],
        emphasis: {
          itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' }
        }
      }
    ]
  });
  window.addEventListener('resize', () => { pieChartInstance && pieChartInstance.resize(); });
}

function renderCategoryLineChart() {
  if (!document.getElementById('category-line-chart')) return;
  if (!categoryLineChartInstance) {
    categoryLineChartInstance = echarts.init(document.getElementById('category-line-chart'));
  }
  // 获取所有账单涉及的日期（天）
  const days = Array.from(new Set(bills.value.map(b => b.date.split('T')[0]))).sort();
  // 按天统计每个分类的金额
  const dayCategoryMap = {};
  days.forEach(day => { dayCategoryMap[day] = {}; });
  bills.value.forEach(b => {
    const day = b.date.split('T')[0];
    if (!dayCategoryMap[day][b.category]) dayCategoryMap[day][b.category] = 0;
    const amount = b.type === '支出' ? -Number(b.amount) : Number(b.amount);
    dayCategoryMap[day][b.category] += amount;
  });
  // 获取所有分类
  const allCategories = Array.from(new Set(bills.value.map(b => b.category)));
  // 每个分类每天金额
  const series = allCategories.map(cat => ({
    name: cat,
    type: 'line',
    data: days.map(d => dayCategoryMap[d][cat] || 0)
  }));
  categoryLineChartInstance.setOption({
    title: { text: '分类金额趋势', left: 'center' },
    tooltip: { trigger: 'axis' },
    legend: { data: allCategories, top: 30 },
    xAxis: { type: 'category', data: days },
    yAxis: { type: 'value' },
    series
  });
  window.addEventListener('resize', () => { categoryLineChartInstance && categoryLineChartInstance.resize(); });
}

const sortedBills = computed(() =>
  [...bills.value].sort((a, b) => new Date(b.date) - new Date(a.date))
);
</script>

<style scoped>
.container {
  max-width: 900px;
  min-width: 340px;
  margin: 40px auto;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 8px #eee;
  padding: 32px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  box-sizing: border-box;
}
h1 {
  text-align: center;
  margin-bottom: 24px;
}
.bill-form {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 18px;
  align-items: center;
}
.form-fields {
  display: flex;
  gap: 16px;
  width: 100%;
}
.date-input-wrapper {
  position: relative;
  flex: 1;
}
.date-input-wrapper input[type="date"] {
  width: 100%;
  padding-right: 28px;
  height: 36px;
}
.date-icon {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  font-size: 18px;
  color: #aaa;
}
.form-actions {
  display: flex;
  flex-direction: row;
  gap: 10px;
  justify-content: flex-end;
  width: 100%;
  margin-top: 8px;
}
.main-btn {
  background: #42b983;
  color: #fff;
  border: none;
  border-radius: 20px;
  padding: 8px 24px;
  font-size: 16px;
  cursor: pointer;
  transition: background 0.2s;
}
.main-btn:hover {
  background: #369870;
}
.cancel-btn {
  background: #aaa;
}
.export-btn {
  background: #35495e;
}
.bill-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 10px;
}
.bill-table th, .bill-table td {
  border: 1px solid #eee;
  padding: 8px 6px;
  text-align: center;
}
.bill-table th {
  background: #f8f8f8;
}
.bill-table tr:nth-child(even) {
  background: #fafafa;
}
@media (max-width: 900px) {
  .container {
    max-width: 100vw;
    padding: 16px 4px;
  }
  .form-fields {
    flex-direction: column;
    gap: 10px;
  }
}
.form-fields select {
  flex: 1;
  padding: 6px 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  height: 36px;
}
.analysis-area {
  width: 100%;
  margin: 32px 0 0 0;
  background: #f8f8f8;
  border-radius: 8px;
  padding: 24px 16px;
  box-sizing: border-box;
}
</style>
